#include "tomosim.h"

TomoSim::TomoSim(QWidget *parent) :
	QMainWindow(parent), num_cameras_(3), p_dist_(NULL){
	ui.setupUi(this);
	QList<int> list, list1;
	list << 800 << 400;
	list1 << 200 << 600;
	ui.splitter->setSizes(list);
	ui.splitter_2->setSizes(list1);

        QFileSystemModel* fmodel = new QFileSystemModel(parent);
        fmodel->setRootPath(QDir::currentPath());
        ui.treeView->setModel(fmodel);
        ui.treeView->setRootIndex(fmodel->index(QDir::currentPath()));

        //camera_pos_ << Point3D<float> (5.0, 0.0, 0.0) << Point3D<float> (0.0, 5.0,
        //		0.0) << Point3D<float> (0.0, 0.0, 5.0);
        renderer_ = vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer < vtkRenderWindow > renWin
                        = ui.qvtkWidget->GetRenderWindow(); //vtkSmartPointer<vtkRenderWindow>::New();
        renWin->AddRenderer(renderer_);

        renderer_->SetBackground(0, 0, 0);
        //renWin->SetSize(800, 400);
        vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
        cube->SetCenter(0,0,0);
        cube->SetXLength(4);
        cube->SetYLength(4);
        cube->SetZLength(2);

        vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        cubeMapper->SetInputConnection(cube->GetOutputPort());
        tank_ = vtkSmartPointer<vtkActor>::New();
        tank_->SetMapper(cubeMapper);
        tank_->GetProperty()->SetEdgeVisibility(true);
        tank_->GetProperty()->SetEdgeColor(1,1,1);
        tank_->GetProperty()->SetOpacity(0.5);
        tank_->GetProperty()->SetColor(1,1,1);
        renderer_->AddActor(tank_);
        // Set up the lighting.
        //
        light_ = vtkSmartPointer<vtkLight>::New();
        light_->SetFocalPoint(0, 0, 0);
        light_->SetPosition(0, 2, 0);
        light_->SetIntensity(ui.ledLightIntensity->text().toFloat());
        renderer_->AddLight(light_);

        // We want to eliminate perspective effects on the apparent lighting.
        // Parallel camera projection will be used. To zoom in parallel projection
        // mode, the ParallelScale is set.
        //
        renderer_->GetActiveCamera()->SetFocalPoint(0, 0, 0);
        renderer_->GetActiveCamera()->SetPosition(0, 0, 4);
        renderer_->GetActiveCamera()->SetViewUp(0, 1, 0);
        renderer_->GetActiveCamera()->ParallelProjectionOff();
        //renderer_->ResetCamera();
        renderer_->GetActiveCamera()->SetParallelScale(1);
        cameras_.append(renderer_->GetActiveCamera());

        vtkSmartPointer<vtkCamera> cam2 = vtkSmartPointer<vtkCamera>::New();
        cam2->SetPosition(3.46,0,2);
        cam2->SetFocalPoint(0,0,0);
        cam2->ParallelProjectionOff();
        cam2->SetParallelScale(1);

        cameras_.append(cam2);

        vtkSmartPointer<vtkCamera> cam3 = vtkSmartPointer<vtkCamera>::New();
        cam3->SetPosition(-3.46,0,2);
        cam3->SetFocalPoint(0, 0, 0);
        cam3->ParallelProjectionOff();
        cam3->SetParallelScale(1);
        cameras_.append(cam3);
}

TomoSim::~TomoSim() {

}

void TomoSim::on_actionOpen_File_triggered() {
	QFileDialog fdialog(this);
	fdialog.setAcceptMode(QFileDialog::AcceptOpen);
	fdialog.setFileMode(QFileDialog::ExistingFiles);
	fdialog.setViewMode(QFileDialog::Detail);
	QStringList fileNames;
	if (fdialog.exec())
		fileNames = fdialog.getOpenFileNames();
	//one data file is selected, treat it as the 3D coordination file.

	if (fileNames.length() == 1) {
		p_dist_ = new ParticleDistribution(fileNames[0],
				ui.ledNumParticles->text().toInt());
	}
}

void TomoSim::on_actionExit_triggered() {
	this->close();
}

void TomoSim::on_pushButton_clicked() {

        QModelIndexList flist = ui.treeView->selectionModel()->selectedIndexes();

        if (flist.length()>1){
            if(p_dist_!=NULL)
                delete p_dist_;
            QString fname = ((QFileSystemModel*)ui.treeView->model())->filePath(flist[0]);
            p_dist_ = new ParticleDistribution(fname,ui.ledNumParticles->text().toInt());
       }

        light_->SetIntensity(ui.ledLightIntensity->text().toFloat());
	// The following lines create a sphere represented by polygons.
	//
	vtkSmartPointer < vtkSphereSource > sphere = vtkSmartPointer<
			vtkSphereSource>::New();
	sphere->SetThetaResolution(100);
	sphere->SetPhiResolution(50);
        sphere->SetRadius(0.01);

	// The mapper is responsible for pushing the geometry into the graphics
	// library. It may also do color mapping, if scalars or other attributes
	// are defined.
	//
	vtkSmartPointer < vtkPolyDataMapper > sphereMapper = vtkSmartPointer<
			vtkPolyDataMapper>::New();
	sphereMapper->SetInputConnection(sphere->GetOutputPort());

	// Create the graphics structure. The renderer renders into the
	// render window. The render window interactor captures mouse events
	// and will perform appropriate camera or actor manipulation
	// depending on the nature of the events.
	//

	//vtkSmartPointer < vtkRenderWindowInteractor > iren = vtkSmartPointer< vtkRenderWindowInteractor>::New();
	//iren->SetRenderWindow(renWin);
        if(p_dist_!=NULL)
	for (int i = 0; i < this->p_dist_->NumParticles(); i++) {
		// The actor is a grouping mechanism: besides the geometry (mapper), it
		// also has a property, transformation matrix, and/or texture map.
		// In this example we create eight different spheres (two rows of four
		// spheres) and set the specular lighting coefficients. A little ambient
		// is turned on so the sphere is not completely black on the back side.
		//
		vtkSmartPointer < vtkActor > sphere1 = vtkSmartPointer<vtkActor>::New();
		sphere1->SetMapper(sphereMapper);
		sphere1->GetProperty()->SetColor(1, 1, 1);
		sphere1->SetPosition((*p_dist_)[i].X(),(*p_dist_)[i].Y(),(*p_dist_)[i].Z());
		//sphere1->GetProperty()->SetAmbient(0.3);
		//sphere1->GetProperty()->SetDiffuse(0.0);
		//sphere1->GetProperty()->SetSpecular(1.0);
		//sphere1->GetProperty()->SetSpecularPower(5.0);
		// Add the actors to the renderer, set the background and size.
		//
                renderer_->AddActor(sphere1);
	}
	// This starts the event loop and invokes an initial render.
	//
	//iren->Initialize();
	//iren->Start();
        renderer_->Render();
}

void TomoSim::on_comboBox_currentIndexChanged(int index){
    renderer_->SetActiveCamera(cameras_[index]);

}

void TomoSim::on_pushButton_2_clicked(){
    renderer_->RemoveAllViewProps();
    renderer_->AddActor(tank_);
}
